import * as 功能 from '../全局对象/功能'




const g = {
    //在售数量
    在售数: "在售数",
    出售计数: "出售计数", // 大于5个以后, 开始永久收费, 一个5钻石

    //订单状态
    出售中: 0,
    已售出: 1,
    完成: 2,
    主动取回: 3,
    超时: -1,

    //交易中心显示类型
    全部商品: 0,
    出售列表: 1,
    装备: 2,
    材料: 3,

    类型: {
        装备: 0,
        材料: 1
    }
}


export function Main(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {
    显示交易中心(Player, Npc, 0, g.全部商品)
    //显示交易中心(Player, 0)
}
export function 翻页(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {
    let 页码 = Args.Int[0]
    let 类型 = Args.Int[1]
    显示交易中心(Player, Npc, 页码, 类型)
}


function 读数据库(Player: TPlayObject, 显示类型: number): TDataSet {
    let 语句 = ""
    switch (显示类型) {
        case g.全部商品:
            语句 = `SELECT * FROM 交易中心 WHERE server = '${GameLib.ServerName}' AND 订单状态 = ${g.出售中}`
            break;
        case g.出售列表:
            语句 = `SELECT * FROM 交易中心 WHERE server = '${GameLib.ServerName}' AND 订单状态 != ${g.完成} AND 订单状态 != ${g.主动取回} and 出售人 = '${Player.Name}'`
            break;
        case g.材料:
            语句 = `SELECT * FROM 交易中心 WHERE server = '${GameLib.ServerName}' AND 订单状态 = ${g.出售中} and 物品类型 = ${g.类型.材料}`
            break;
        case g.装备:
            语句 = `SELECT * FROM 交易中心 WHERE server = '${GameLib.ServerName}' AND 订单状态 = ${g.出售中} and 物品类型 = ${g.类型.装备}`
            break;
        default:
            break;
    }
    return GameLib.DBEngine.Query('数据库', 语句)
}

function 显示交易中心(Player: TPlayObject, Npc: TNormNpc, 页码: number, 显示类型: number) {

    let 商品列表: TDataSet = 读数据库(Player, 显示类型)

    if (商品列表 == undefined) {
        功能.系统.信息框(Player, "交易中心维护中")
        return
    }

    商品列表.Open()
    let str = ""
    let 物品总数 = 商品列表.RecordCount
    let 显示上限 = 7
    let 总页码 = Math.ceil(物品总数 / 显示上限)
    页码 = 页码 >= 总页码 - 1 ? 总页码 - 1 : 页码
    页码 = 页码 < 0 ? 0 : 页码
    let 索引头 = 页码 * 显示上限
    let 索引尾 = 页码 * 显示上限 + 显示上限
    let 索引 = -1


    for (let i = 0; i < 物品总数; i++) {
        // 遍历已经超过最大显示i了, 直接跳出循环, 节省资源
        if (i > 索引尾) {
            break
        }
        if (商品列表.IsEmpty() == true) {
            break
        }
        if (i >= 索引头 && i < 索引尾) {
            索引++
            //console.log(i, 索引头, 索引尾, 商品列表.FieldByName('物品名').AsString)

            let y = 索引 * 50 + 130
            let 序号 = i + 1
            let 数据库ID = 商品列表.FieldByName('ID').AsInteger
            let 物品名 = 商品列表.FieldByName('物品名').AsString
            let 颜色 = 商品列表.FieldByName('物品颜色').AsInteger
            let 物品str = 商品列表.FieldByName('物品s1').AsString
            let 数量 = 商品列表.FieldByName('数量').AsInteger
            let 价格 = 商品列表.FieldByName('出售价格').AsInteger
            let 订单状态 = 商品列表.FieldByName('订单状态').AsInteger
            let 换算 = ""
            let 显示文字 = ""
            let 换算颜色 = 255
            let 价格颜色 = 255
            let 我的钻石 = 功能.获取.钻石(Player)
            if (显示类型 == g.出售列表) {
                switch (订单状态) {
                    case g.出售中: 换算 = "出售中"; 换算颜色 = 255; 显示文字 = "取回"; break;
                    case g.已售出: 换算 = `已售出`; 换算颜色 = 250; 显示文字 = "取出钻石"; break;
                    case g.超时: 换算 = "超时"; 换算颜色 = 249; 显示文字 = "取回"; break;
                }

            } else {
                换算 = 商品列表.FieldByName('换算').AsString
                if (我的钻石 >= 价格) {
                    价格颜色 = 250
                } else {
                    价格颜色 = 249
                }

            }
            str += `
            {s=${序号};c=255;x=50;y=${y}}
            {s=${物品名};c=${颜色};x=110;y=${y}}
            {u=${物品str};x=215;y=${y}}
            {s=${数量};x=275;y=${y}}
            {s=${价格};x=340;y=${y};c=${价格颜色}}
            {s=${换算};x=420;y=${y};c=${换算颜色}}    
            `//(}钻石)
            if (显示类型 == g.出售列表) {
                //显示文字=取回     显示文字=取出钻石
                str += `<{s=${显示文字};x=580;y=${y}}/@交易中心.${显示文字}(${页码},${显示类型},${数据库ID})>`
                if (订单状态 == g.已售出) {
                    str += `{s=(收益：${Math.ceil(价格 * 0.95)} 钻石);x=630;y=${y};c=250}`
                }
            } else {
                str += `<{s=购买;x=580;y=${y}}/@交易中心.购买(${页码},${显示类型},${数据库ID},${价格},${物品名})>`
            }
        }
        商品列表.Next();
    }

    //释放会报 TActor::Run 1 0 81 错误
    //商品列表.Free()

    let 颜色 = 0
    let 全部物品 = ""
    let 我的出售 = ""
    let 标签 = ""
    let y = 索引 == -1 ? 490 : 478  //当前页面如果没物品会让Y坐标偏移,修复一下
    let y2 = 索引 == -1 ? 65 : 53  //当前页面如果没物品会让Y坐标偏移,修复一下
    switch (显示类型) {
        case g.全部商品:
            颜色 = 251;
            全部物品 = `{s=全部物品;x=80;y=${y};c=236}`
            我的出售 = `<{s=我的出售;x=160;y=${y}}/@交易中心.翻页(0,${g.出售列表})>`
            标签 = `
            {s=[全部];x=80;y=${y2};c=236}
            <{s=[装备];x=120;y=${y2}}/@交易中心.翻页(0,${g.装备})>
            <{s=[材料];x=160;y=${y2}}/@交易中心.翻页(0,${g.材料})>`
            break;
        case g.出售列表:
            颜色 = 254;
            全部物品 = `<{s=全部物品;x=80;y=${y}}/@交易中心.翻页(0,${g.全部商品})>`
            我的出售 = `{s=我的出售;x=160;y=${y};c=236}`
            标签 = `
            `
            break;
        case g.装备:
            颜色 = 251;
            全部物品 = `<{s=全部物品;x=80;y=${y}}/@交易中心.翻页(0,${g.全部商品})>`
            我的出售 = `<{s=我的出售;x=160;y=${y}}/@交易中心.翻页(0,${g.出售列表})>`
            标签 = `
            <{s=[全部];x=80;y=${y2}}/@交易中心.翻页(0,${g.全部商品})>
            {s=[装备];x=120;y=${y2};c=236}
            <{s=[材料];x=160;y=${y2}}/@交易中心.翻页(0,${g.材料})>`
            break;
        case g.材料:
            颜色 = 251;
            全部物品 = `<{s=全部物品;x=80;y=${y}}/@交易中心.翻页(0,${g.全部商品})>`
            我的出售 = `<{s=我的出售;x=160;y=${y}}/@交易中心.翻页(0,${g.出售列表})>`
            标签 = `
            <{s=[全部];x=80;y=${y2}}/@交易中心.翻页(0,${g.全部商品})>
            <{s=[装备];x=120;y=${y2}}/@交易中心.翻页(0,${g.装备})>
            {s=[材料];x=160;y=${y2};c=236}`
            break;
    }
    str += `<&{s=上一页;x=560;y=${y};c=${颜色}}/@交易中心.翻页(${页码 - 1},${显示类型})>
    {s= ${页码 + 1}/${总页码}  ;x=610;y=${y}}
    <&{s=下一页;x=653;y=${y};c=${颜色}}/@交易中心.翻页(${页码 + 1},${显示类型})>
    <{s=上架物品;x=240;y=${y}}/@交易中心.弹出出售窗口>
    {s=筛选：;x=40;y=${y2};c=254}
   `
    str += 全部物品 + 我的出售 + 标签

    // console.log(页码 + " " + 索引)
    // console.log(str)
    // if (页码 == 0 || 索引 > -1) {
    Npc.SayEx(Player, "交易中心", str);
    // Player.SayEx('交易中心', str)
    // }


}
export function 取出钻石(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {

    let 页码 = Args.Int[0]
    let 显示类型 = Args.Int[1]
    let 数据库ID = Args.Int[2]
    let 是否成功 = 订单.取出钻石(数据库ID, Player)

    if (是否成功 == false) {
        功能.系统.信息框(Player, "取出失败,请联系GM")
        return
    }

    Player.V[g.在售数]--
    Player.V[g.在售数] = Player.V[g.在售数] < 0 ? 0 : Player.V[g.在售数]


    显示交易中心(Player, Npc, 页码, 显示类型)


}
export function 取回(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {

    let 页码 = Args.Int[0]
    let 显示类型 = Args.Int[1]
    let 数据库ID = Args.Int[2]
    let 物品对象 = 订单.取回物品(数据库ID, Player)

    if (物品对象 == undefined) {
        功能.系统.信息框(Player, "取回物品失败, 请重试或联系GM")
        return
    }

    Player.AddItemToBag(物品对象)
    Player.SendMessage('取回:' + 物品对象.Name, 1)
    Player.V[g.在售数]--
    Player.V[g.在售数] = Player.V[g.在售数] < 0 ? 0 : Player.V[g.在售数]


    显示交易中心(Player, Npc, 页码, 显示类型)


}

export function 购买(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {


    let 页码 = Args.Int[0]
    let 显示类型 = Args.Int[1]
    let 数据库ID = Args.Int[2]
    let 出售价格 = Args.Int[3]
    let 物品名 = Args.Str[4]



    if (功能.获取.钻石(Player) < 出售价格) {
        Player.SendMessage('钻石不足' + 出售价格 + ", 无法购买")
        return
    }
    if (订单.购买商品(数据库ID, Player, 出售价格) == true) {
        功能.扣除.钻石(Player, 出售价格, "交易中心购买,数据库ID:" + 数据库ID)
        Player.SendMessage('购买成功:' + 物品名, 1)
    } else {
        功能.系统.信息框(Player, "物品可能已经被别人买走了!")
    }



    显示交易中心(Player, Npc, 页码, 显示类型)
}

// function 从交易中心复制物品(params:type) {

// }


class 订单格式 {
    物品名: string
    物品对象: TUserItem
    出售人: string
    出售价格: number
    换算: string
    状态: string
}

const 订单 = {

    生成订单(Player: TPlayObject, Item: TUserItem, 出售价格: number): number {
        let 数量 = 是否为装备(Item) == true ? 1 : Item.Dura
        let 物品类型 = 是否为装备(Item) == true ? g.类型.装备 : g.类型.材料
        数量 = 数量 <= 0 ? 1 : 数量
        let 换算 = ""
        if (数量 > 1) {
            换算 = "1钻石 = " + (数量 / 出售价格).toFixed(3) + "个"
        }

        //物品s1 显示用    物品s2 转换对象用
        let 返回 = GameLib.DBEngine.ExecSQL('数据库', `INSERT INTO 交易中心 set
            server = '${GameLib.ServerName}',
            订单状态 = ${g.出售中},
            物品名 = '${Item.Name}',
            物品颜色 = ${Item.Color},
            物品类型 = ${物品类型},
            数量 = ${数量},
            物品s1 ='${Item.MakeString()}',      
            物品s2 = '${GameLib.SaveUserItemToString(Item)}',   
            换算 = '${换算}', 
            出售时间 = now(),  
            出售价格 = ${出售价格},           
            出售人 = '${Player.Name}'`)

        return 返回
    },
    购买商品(ID: number, 购买人: TPlayObject, 出售价格: number): boolean {
        let 文本列表 = GameLib.CreateStringList()
        文本列表 = GameLib.DBEngine.ValueList('数据库', `SELECT 物品s2 FROM 交易中心 WHERE
        server = '${GameLib.ServerName}' AND 
        ID = ${ID} and 
        出售价格 = ${出售价格} and
        订单状态 = ${g.出售中}
        `);
        if (文本列表.Count == 1) { // 表示这个物品没有被卖出, 并且价格没问题, 没被封包
            //改变订单状态 !!!!!!!! 注意!!!  必须先在上一层函数里校验一下 包里的钱够不够, 只需要校验够不够就行, 其它我这里校验

            购买人.AddItemToBag(GameLib.LoadUserItemFromString(文本列表.GetStrings(0)))
            GameLib.DBEngine.ExecSQL('数据库', `UPDATE 交易中心 SET 
            订单状态 = ${g.已售出},
            购买人 = '${购买人.Name}',
            购买时间 = now()
            WHERE server = '${GameLib.ServerName}' AND ID = ${ID}`)
            return true
        } else {
            return false // 表示条件不满足, 可能已经被卖出, 可能被封包了校验失败, 不管是啥, 反正就返回假
        }

    },
    取回物品(ID: number, 取回人: TPlayObject): TUserItem {

        let 返回物品对象: TUserItem
        //先查询物品s2 ,如果查询到了  在改订单状态和取回时间, 然后把物品s2 转成物品对象返回
        let 文本列表 = GameLib.CreateStringList()
        文本列表 = GameLib.DBEngine.ValueList('数据库', `SELECT 物品s2 FROM 交易中心 WHERE 
        server = '${GameLib.ServerName}' AND
        订单状态 = ${g.出售中} and
        ID = ${ID} and 
        出售人 = '${取回人.Name}'`);
        if (文本列表.Count == 1) {
            //改取回状态
            let 错误代码 = GameLib.DBEngine.ExecSQL('数据库', `UPDATE 交易中心 SET 订单状态 = ${g.主动取回},取回时间 = now() WHERE server = '${GameLib.ServerName}' AND ID = ${ID}`)
            if (错误代码 == 1) {//1 = 无错误
                return GameLib.LoadUserItemFromString(文本列表.GetStrings(0))
            } else {
                return 返回物品对象
            }

        } else {
            return 返回物品对象
        }
    },

    取出钻石(ID: number, 取回人: TPlayObject): boolean {

        //先查询出售价格 ,如果查询到了  在改订单状态和取回时间
        let 文本列表 = GameLib.CreateStringList()
        文本列表 = GameLib.DBEngine.ValueList('数据库', `SELECT 出售价格 FROM 交易中心 WHERE 
        server = '${GameLib.ServerName}' AND
        订单状态 = ${g.已售出} and
        ID = ${ID} and 
        出售人 = '${取回人.Name}'`);
        if (文本列表.Count == 1) {
            //改取回状态
            let 错误代码 = GameLib.DBEngine.ExecSQL('数据库', `UPDATE 交易中心 SET 订单状态 = ${g.完成},取回时间 = now() WHERE server = '${GameLib.ServerName}' AND ID = ${ID}`)
            if (错误代码 == 1) {//1 = 无错误
                let 钻石 = Number(文本列表.GetStrings(0))
                钻石 = Math.ceil(钻石 * 0.95) // 扣除5% 手续费
                功能.增加.钻石(取回人, 钻石, "卖出物品,数据库ID:" + ID)
                取回人.SendMessage('成功取出: ' + 钻石 + "钻石, 祝老板生意兴隆, 发大财!", 1)
                return true
            } else {
                return false
            }

        } else {
            return false
        }
    },
}


function 是否为装备(物品对象: TUserItem): boolean {
    let strmode = [5, 10, 11, 15, 19, 24, 23, 27, 28]
    if (strmode.indexOf(物品对象.StdMode) > -1) {
        return true
    }
    return false
}


export function 弹出出售窗口(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {
    let 手续费 = Player.V[g.出售计数] <= 5 || Player.V[g.出售计数] == undefined ? 0 : 5
    let str = `
    {s=放入物品;x=50;y=130;c=248}
    {s=手续费：;x=120;y=80;c=254}{s=${手续费} 钻石;x=170;y=80;c=250}
    {s=出售价格：;x=120;y=105;c=254}`
    Npc.SayEx(Player, "交易中心卖物品", str)
}

export function 出售预览(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {
    let 放入的物品 = Player.GetCustomItem(0)
    let 出售价格 = Args.Int[0]
    if (放入的物品 == undefined) {
        功能.系统.信息框(Player, "请放入要出售的物品")
        return
    }
    if (出售价格 <= 0) {
        功能.系统.信息框(Player, "请输入价格")
        return
    }
    let 数量 = 是否为装备(放入的物品) == true ? 1 : 放入的物品.Dura
    数量 = 数量 <= 0 ? 1 : 数量
    let 换算 = ""
    if (数量 > 1) {
        换算 = "1钻石 = " + (数量 / 出售价格).toFixed(3) + "个"
    }
    功能.系统.信息框(Player, `{s=出售的物品：}{s=${放入的物品.Name};c=${放入的物品.Color}}   {s=价格：${出售价格}}  {s=换算：}{s=${换算};c=250}`)

}
export function 出售物品(Npc: TNormNpc, Player: TPlayObject, Args: TArgs): void {
    let 放入的物品 = Player.GetCustomItem(0)
    let 出售价格 = Args.Int[0]
    let 手续费 = Player.V[g.出售计数] <= 5 || Player.V[g.出售计数] == undefined ? 0 : 5
    if (功能.背包.物品是否绑定(放入的物品) == true) {
        功能.系统.信息框(Player, "绑定物品无法上架")
        return
    }

    if (Player.V[g.在售数] >= 20) {
        功能.系统.信息框(Player, "你的在售物品已达到20个, 无法继续出售上架了")
        return
    }
    if (放入的物品 == undefined) {
        功能.系统.信息框(Player, "请放入要出售的物品")
        return
    }
    if (出售价格 <= 0) {
        功能.系统.信息框(Player, "请输入价格")
        return
    }
    if (功能.获取.钻石(Player) < 手续费) {
        功能.系统.信息框(Player, "钻石不足" + 手续费 + ", 无法上架")
        return
    }


    功能.扣除.钻石(Player, 手续费, "上架" + 放入的物品.Name)
    let 数量 = 是否为装备(放入的物品) == true ? 1 : 放入的物品.Dura
    数量 = 数量 <= 0 ? 1 : 数量
    let 是否成功 = 订单.生成订单(Player, 放入的物品, 出售价格)
    if (是否成功 > 0) {
        Player.SendMessage(`{s=你以 }{s=${出售价格}钻石;c=249}{s=的价格上架了}{s=${数量}个;}{s=${放入的物品.Name};c=${放入的物品.Color}}`, 1)
        Player.DeleteBagItem(放入的物品, 数量)//删除    
        Player.V[g.在售数] = Player.V[g.在售数] == undefined ? 1 : Player.V[g.在售数] + 1
        Player.V[g.出售计数] = Player.V[g.出售计数] == undefined ? 1 : Player.V[g.出售计数] + 1
        弹出出售窗口(Npc, Player, undefined)
    } else {
        功能.系统.信息框(Player, "上架失败,请联系GM")
    }

}

